import ctypes
import time
import os
import gym_pih.hardware.tisgrabber as tis
import cv2
import numpy as np

current_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)))

class Camera():
    def __init__(self,resoultion="1280x720"):
        """
        Initializes the Imagingsource_for_windows class.

        Args:
            resolution (str): The resolution of the video format. Default is "1280x720". Options are such as "640x480", "1280x720", "1920x1080".

        """
        self.ic = ctypes.cdll.LoadLibrary(current_path+"/tisgrabber_x64.dll")
        tis.declareFunctions(self.ic)
        self.ic.IC_InitLibrary(0)
        self.hGrabber = tis.openDevice(self.ic)
        self.Width = ctypes.c_long()
        self.Height = ctypes.c_long()
        self.BitsPerPixel = ctypes.c_int()
        self.colorformat = ctypes.c_int()
        self.ic.IC_SetVideoFormat(self.hGrabber, tis.T(f"RGB32 ({resoultion})"))
        self.ic.IC_SetFrameRate(self.hGrabber, ctypes.c_float( 60.0))

    def Open(self):
        if (self.ic.IC_IsDevValid(self.hGrabber)):
            self.ic.IC_StartLive(self.hGrabber, 0)
        else:
            print("can not open camera")
            exit(1)

    def Close(self):
        self.ic.IC_StopLive(self.hGrabber)

    def GetImage(self):
        if self.ic.IC_SnapImage(self.hGrabber, 2000) == tis.IC_SUCCESS:
            # Query the values of image description
            self.ic.IC_GetImageDescription(self.hGrabber, self.Width, self.Height,
                                      self.BitsPerPixel, self.colorformat)
            # Calculate the buffer size
            bpp = int(self.BitsPerPixel.value / 8.0)
            buffer_size = self.Width.value * self.Height.value * self.BitsPerPixel.value
            # Get the image data
            imagePtr = self.ic.IC_GetImagePtr(self.hGrabber)
            imagedata = ctypes.cast(imagePtr,
                                    ctypes.POINTER(ctypes.c_ubyte *
                                                   buffer_size))
            # Create the numpy array
            image = np.ndarray(buffer=imagedata.contents,
                               dtype=np.uint8,
                               shape=(self.Height.value,
                                      self.Width.value,
                                      bpp))
            
            
            # 将图像旋转180度
            rotated_image = cv2.rotate(image, cv2.ROTATE_180)

            # 对旋转后的图像进行水平镜像
            image = cv2.flip(rotated_image, 1)  # 水平翻转，参数为 1
            return True,image
        else:
            return False,None

    def SetProperty(self,propertyname,type,value):
        '''

        Args:
            propertyname: 设置的属性字符串
            type:"Auto" or "Value"
            value:如果是value，则传入数字

        Returns:

        '''
        if(type=="Auto"):
            exposureauto = ctypes.c_long()
            self.ic.IC_SetPropertySwitch(self.hGrabber, tis.T(propertyname), tis.T("Auto"), 1)
        if(type=="Value"):
            self.ic.IC_SetPropertySwitch(self.hGrabber, tis.T(propertyname), tis.T("Auto"), 0)
            self.ic.IC_SetPropertyAbsoluteValue(self.hGrabber, tis.T(propertyname), tis.T("Value"),
                                           ctypes.c_float(value))

    def GetProerty(self,propertyname):
        gain = ctypes.c_long()
        self.ic.IC_GetPropertyValue(self.hGrabber, tis.T(propertyname), tis.T("Value"), gain)
        return gain

if __name__ == '__main__':
    camera= Camera()
    camera.Open()
    camera.SetProperty("Gain","Value",0)
    camera.SetProperty("Exposure","Value",float(1/30))
    v=camera.GetProerty("Exposure")
    print(v)

    cv2.namedWindow("slope", 0)
    cv2.resizeWindow("slope", 1280 , 720)
    cv2.namedWindow("obs", 0)
    cv2.resizeWindow("obs", 480 , 480)
    cv2.namedWindow("rew", 0)
    cv2.resizeWindow("rew", 480 , 480)

    time.sleep(1)
    while True:
        _,image=camera.GetImage()
        obs_image = image[40:720, 260:900]
        rew_image = image[130:,250:1020]
        obs_image = cv2.resize(obs_image, (64, 64))
        cv2.imshow('slope', image)
        cv2.imshow('obs', obs_image)
        cv2.imshow('rew', rew_image)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        if cv2.waitKey(1) & 0xFF == ord('s'):
            cv2.imwrite("image.jpg", image)
    camera.Close()
    # _,image=camera.GetImage()
    # cv2.imwrite("image.jpg", image)

# camera= Camera()
# camera.Open()
# camera.SetProperty("Gain","Value",5)
# camera.SetProperty("Exposure","Value",float(1/299))
# v=camera.GetProerty("Gain")
# print(v)
#
#
#
# time.sleep(2)
#
# _,image=camera.GetImage()
# cv2.namedWindow("result", 0)
# cv2.resizeWindow("result", 320, 320)  # 设置窗口大小
# cv2.imshow('result', image)
# cv2.waitKey(0)
if __name__=="__main___":
    camera= Camera()
    camera.Open()
    camera.SetProperty("Gain","Value",0)
    camera.SetProperty("Exposure","Value",float(1/2000))
    v=camera.GetProerty("Gain")
    print(v)

    cv2.namedWindow("slope", 0)
    cv2.resizeWindow("slope", 1280 , 720)
    cv2.namedWindow("obs", 0)
    cv2.resizeWindow("obs", 480 , 480)
    cv2.namedWindow("rew", 0)
    cv2.resizeWindow("rew", 480 , 480)

    time.sleep(1)
    while True:
        _,image=camera.GetImage()
        obs_image = image[40:720, 360:1000]
        rew_image = image[565:629,648:712]
        obs_image = cv2.resize(obs_image, (64, 64))
        cv2.imshow('slope', image)
        cv2.imshow('obs', obs_image)
        cv2.imshow('rew', rew_image)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        if cv2.waitKey(1) & 0xFF == ord('s'):
            cv2.imwrite("image.jpg", image)
    camera.Close()
    # _,image=camera.GetImage()
    # cv2.imwrite("image.jpg", image)